package com.powerunion.datacollection.quartz;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerUtils;
import org.quartz.impl.StdSchedulerFactory;
import com.powerunion.datacollection.common.SystemException;
import com.powerunion.datacollection.common.UUIDGenerator;

import java.text.*;
import java.util.Date;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

final public class TaskScheduler {
	private Scheduler theScheduler;
	private static TaskScheduler instance = null;

	private TaskScheduler() {
		SchedulerFactory sf = new StdSchedulerFactory();
		try {
			this.theScheduler = sf.getScheduler();
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 暂停某个计划任务
	 *
	 * @param taskName 任务名称
	 */
	public void pauseTask(String taskName) {
		try {
			this.theScheduler.pauseJob(taskName, Scheduler.DEFAULT_GROUP);
		} catch (SchedulerException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 删除一个计划任务
	 *
	 * @param taskName 任务名称
	 */
	public void deleteTask(String taskName) {
		try {
			this.theScheduler.deleteJob(taskName, Scheduler.DEFAULT_GROUP);
		} catch (SchedulerException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 恢复某个计划任务
	 *
	 * @param taskName 任务名称
	 */
	public void resumeTask(String taskName) {
		try {
			this.theScheduler.resumeJob(taskName, Scheduler.DEFAULT_GROUP);
		} catch (SchedulerException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 计划一个任务
	 *
	 * @param appTaskClass AppTask类
	 * @param taskName 任务名称
	 * @param timeExpression 计划时间表达式<pre>
	 */
	public void schedule(Class appTaskClass, String taskName,
			String timeExpression) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		CronTrigger ct = new CronTrigger();
		ct.setName(UUIDGenerator.generate());
		ct.setJobName(taskName);
		ct.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			ct.setCronExpression(timeExpression);
			this.theScheduler.scheduleJob(jd, ct);
		} catch (ParseException ex) {
			throw new SystemException(ex);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	public void schedule(Class appTaskClass, String taskName,
			String timeExpression, JobDetail jd) {
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		CronTrigger ct = new CronTrigger();
		ct.setName(UUIDGenerator.generate());
		ct.setJobName(taskName);
		ct.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			ct.setCronExpression(timeExpression);
			this.theScheduler.scheduleJob(jd, ct);
		} catch (ParseException ex) {
			throw new SystemException(ex);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 计划一个任务
	 * @param appTaskClass AppTask类
	 * @param taskName 任务名称
	 * @param startTime 开始触发时间
	 * @param repeatCount 重复次数
	 * @param repeatInterval 间隔时间
	 * @param jd
	 */
	public void schedule(Class appTaskClass, String taskName, Date startTime,Date endTime,
			int repeatCount, long repeatInterval, JobDetail jd) {
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		 
		Trigger trigger = new SimpleTrigger(taskName,
				Scheduler.DEFAULT_GROUP, startTime, endTime, repeatCount,
				repeatInterval);

		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 每日定时执行
	 *
	 * @param appTaskClass AppTask任务类
	 * @param taskName 任务名称
	 * @param hour （0－23）小时
	 * @param minute （0－59）分钟
	 */
	public void scheduleDialy(Class appTaskClass, String taskName, int hour,
			int minute) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeDailyTrigger(UUIDGenerator
				.generate(), hour, minute);
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	public void scheduleDialy(Class appTaskClass, String taskName, int hour,
			int minute, JobDetail jd) {
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeDailyTrigger(UUIDGenerator
				.generate(), hour, minute);
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 每周定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param dayOfWeek （1－7）星期
	 * @param hour （0－23）小时
	 * @param minute （0－59）分钟
	 */
	public void scheduleWeekly(Class appTaskClass, String taskName,
			int dayOfWeek, int hour, int minute) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeWeeklyTrigger(UUIDGenerator
				.generate(), dayOfWeek, hour, minute);
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	public void scheduleWeekly(Class appTaskClass, String taskName,
			int dayOfWeek, int hour, int minute, JobDetail jd) {
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeWeeklyTrigger(UUIDGenerator
				.generate(), dayOfWeek, hour, minute);
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 每月定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param dayOfMonth (1-31, or -1)月内某日
	 * @param hour （0－23）小时
	 * @param minute （0－59）分钟
	 */
	public void scheduleMonthly(Class appTaskClass, String taskName,
			int dayOfMonth, int hour, int minute) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeMonthlyTrigger(UUIDGenerator
				.generate(), dayOfMonth, hour, minute);
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	public void scheduleMonthly(Class appTaskClass, String taskName,
			int dayOfMonth, int hour, int minute, JobDetail jd) {
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeMonthlyTrigger(UUIDGenerator
				.generate(), dayOfMonth, hour, minute);
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 立即执行，并可以按重复次数和间隔执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名
	 * @param repeatCount 重复次数
	 * @param repeatInterval 执行间隔 ms毫秒
	 */
	public void scheduleImmediate(Class appTaskClass, String taskName,
			int repeatCount, long repeatInterval) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeImmediateTrigger(UUIDGenerator
				.generate(), repeatCount, repeatInterval);
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 以小时为单位定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param intervalInHours 时间间隔，单位小时，整数
	 */
	public void scheduleHourly(Class appTaskClass, String taskName,
			int intervalInHours) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeHourlyTrigger(intervalInHours);
		trigger.setJobName(taskName);
		trigger.setGroup(UUIDGenerator.generate());
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 以小时为单位定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param intervalInHours 时间间隔，单位小时，整数
	 * @param repeatCount 重复次数
	 */
	public void scheduleHourly(Class appTaskClass, String taskName,
			int intervalInHours, int repeatCount) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeHourlyTrigger(UUIDGenerator
				.generate(), intervalInHours, repeatCount);
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 以分钟为单位定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param intervalInHours 时间间隔，单位分钟，整数
	 * @param repeatCount 重复次数
	 */
	public void scheduleMinutely(Class appTaskClass, String taskName,
			int intervalInMinutes, int repeatCount) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeMinutelyTrigger(UUIDGenerator
				.generate(), intervalInMinutes, repeatCount);
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 以分钟为单位定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param intervalInHours 时间间隔，单位分钟，整数
	 */
	public void scheduleMinutely(Class appTaskClass, String taskName,
			int intervalInMinutes) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeMinutelyTrigger(intervalInMinutes);
		trigger.setName(UUIDGenerator.generate());
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 以分钟为单位定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param intervalInHours 时间间隔，单位分钟，整数
	 */
	public void scheduleMinutely(Class appTaskClass, String taskName,
			int intervalInMinutes, JobDetail jd) {
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		Trigger trigger = TriggerUtils.makeMinutelyTrigger(intervalInMinutes);
		trigger.setName(UUIDGenerator.generate());
		trigger.setJobName(taskName);
		trigger.setGroup(Scheduler.DEFAULT_GROUP);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 以秒为单位定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param intervalInHours 时间间隔，单位秒，整数
	 * @param repeatCount 重复次数
	 */
	public void scheduleSecondly(Class appTaskClass, String taskName,
			int intervalInSeconds, int repeatCount) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		SimpleTrigger trigger = new SimpleTrigger(UUIDGenerator.generate(),
				Scheduler.DEFAULT_GROUP);
		trigger.setRepeatInterval(intervalInSeconds * 1000l);
		trigger.setRepeatCount(repeatCount);
		trigger.setJobName(taskName);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 以秒为单位定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param intervalInHours 时间间隔，单位秒，整数
	 */
	public void scheduleSecondly(Class appTaskClass, String taskName,
			int intervalInSeconds) {
		JobDetail jd = new JobDetail();
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		SimpleTrigger trigger = new SimpleTrigger(UUIDGenerator.generate(),
				Scheduler.DEFAULT_GROUP);
		trigger.setRepeatInterval(intervalInSeconds * 1000l);
		trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
		trigger.setJobName(taskName);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 以秒为单位定时执行
	 *
	 * @param appTaskClass 任务类
	 * @param taskName 任务名称
	 * @param intervalInHours 时间间隔，单位秒，整数
	 * @param repeatCount 重复次数
	 */
	public void scheduleSecondly(Class appTaskClass, String taskName,
			int intervalInSeconds, int repeatCount, JobDetail jd) {
		jd.setGroup(Scheduler.DEFAULT_GROUP);
		jd.setJobClass(appTaskClass);
		jd.setName(taskName);
		SimpleTrigger trigger = new SimpleTrigger(UUIDGenerator.generate(),
				Scheduler.DEFAULT_GROUP);
		trigger.setRepeatInterval(intervalInSeconds * 1000l);
		trigger.setRepeatCount(repeatCount);
		trigger.setJobName(taskName);
		try {
			this.theScheduler.scheduleJob(jd, trigger);
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	public void start() {
		try {
			this.theScheduler.start();
		} catch (SchedulerException ex) {
			throw new SystemException(ex);
		}
	}

	/**
	 * 暂停所有的计划执行的任务
	 */
	public void pauseAll() {
		try {
			this.theScheduler.pauseAll();
		} catch (SchedulerException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 恢复所有被暂停的计划任务
	 */
	public void resumeAll() {
		try {
			this.theScheduler.resumeAll();
		} catch (SchedulerException ex) {
			ex.printStackTrace();
		}
	}

	public void shutdown(boolean waitForJobsToComplete) {
		try {
			this.theScheduler.shutdown(waitForJobsToComplete);
		} catch (SchedulerException ex) {
			ex.printStackTrace();
		}
	}

	public boolean isShutdown() {
		try {
			return this.theScheduler.isShutdown();
		} catch (SchedulerException ex) {
			ex.printStackTrace();
			return false;
		}
	}

	public void shutdown() {
		try {
			this.theScheduler.shutdown();
		} catch (SchedulerException ex) {
			ex.printStackTrace();
		}
	}

	public static TaskScheduler getInstance() {
		if (instance == null) {
			instance = new TaskScheduler();
		}
		return instance;
	}

	public static Scheduler getScheduler(HttpServletRequest request)
			throws SchedulerException {

		ServletContext ctx = request.getSession().getServletContext();

		StdSchedulerFactory factory = (StdSchedulerFactory) ctx
				.getAttribute("org.quartz.impl.StdSchedulerFactory.KEY");

		return factory.getScheduler();
	}

//		public static void main(String[] args){
//			JobDetail jd = new JobDetail();
//			jd.getJobDataMap()
//					.put("urgenContent", "催办信息");
//			jd.getJobDataMap().put("userCode", "qyw");
//			jd.getJobDataMap().put("id", "666");
//			jd.getJobDataMap().put(
//							"type",
//							String.valueOf(Constants.TASK_TYPE_SUBMISSIONWORK));
//			StringBuffer taskName = new StringBuffer();
//			taskName.append("sw_urgen6");
//			jd.getJobDataMap().put("taskName", taskName.toString());
//			
//			java.util.Calendar cal = new java.util.GregorianCalendar(
//					2010, 2, 22);
//			// 固定早上10点发送催办信息
//			cal.set(cal.HOUR, 16);
//			cal.set(cal.MINUTE, 27);
//			cal.set(cal.SECOND, 0);
//			cal.set(cal.MILLISECOND, 0);
//			Date startTime = cal.getTime();
//			
//			TaskScheduler.getInstance().schedule(
//					UrgencyTask.class, "sw_urgen6",
//					startTime,3,5000L, jd);
//		}

}
